package com.hjk.waibao.mj.interceptor;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.hjk.waibao.mj.annotation.ModelPara;
import com.hjk.waibao.mj.annotation.PostPara;
import com.hjk.waibao.mj.exception.CustomException;
import com.hjk.waibao.mj.util.BaseDataConvertUtil;
import com.hjk.waibao.mj.util.ModelAttrPutUtil;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.HttpKit;
import com.jfinal.upload.UploadFile;
import lombok.SneakyThrows;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
import java.util.Map;

public class PostParaInterceptor implements Interceptor {

    @SneakyThrows //忽略抛出异常
    @Override
    public void intercept(Invocation invocation) {
        try {
            JSONObject json = null;
            if ("POST".equals(invocation.getController().getRequest().getMethod())) {
                //获取文件
                if (invocation.getController().getRequest().getContentType() != null &&
                        invocation.getController().getRequest().getContentType().contains("multipart/form-data")) {
                    invocation.getController().getFiles();
                }
                //获取post body中的json
                if (StrUtil.contains(invocation.getController().getRequest().getContentType(), "application/json")) {
                    String jsonString = HttpKit.readData(invocation.getController().getRequest());
                    if (StrUtil.isNotBlank(jsonString)) {
                        json = JSONObject.parseObject(jsonString);
                        for (Map.Entry<String, Object> entry : json.entrySet()) {
                            invocation.getController().setAttr(entry.getKey(), entry.getValue());
                        }
                    }
                    invocation.getController().setAttr("postJson", jsonString);
                }
            }
            if (json == null) {
                json = new JSONObject();
            }
            //获取form-data和get参数
            for (Map.Entry<String, String[]> entry : invocation.getController().getParaMap().entrySet()) {
                if (entry.getValue() != null && entry.getValue().length > 0) {
                    json.put(entry.getKey(), entry.getValue()[0]);
                }
            }
            //设置注解
            setAnnotation(invocation, json);
            invocation.invoke();
        } catch (CustomException e1) {
            throw e1;
        } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e2) {
            e2.printStackTrace();
            throw new Exception("POST映射错误:" + e2.getMessage());
        }
        //删除上传的文件
        try {
            if (invocation.getController().getRequest().getContentType().contains("multipart/form-data")) {
                for (UploadFile uploadFile : invocation.getController().getFiles()) {
                    uploadFile.getFile().delete();
                }
            }
        } catch (Exception e) {

        }
    }

    private void setAnnotation(Invocation invocation, JSONObject json) throws CustomException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        for (int index = 0; index < invocation.getMethod().getParameters().length; index++) {
            Parameter parameter = invocation.getMethod().getParameters()[index];
            if (parameter.getAnnotation(ModelPara.class) != null) {
                //ModelPara类型的注解
                Object instance = parameter.getType().getDeclaredConstructor().newInstance();
                ModelAttrPutUtil.setPara(instance, json);
                invocation.setArg(index, instance);
            } else if (parameter.getAnnotation(PostPara.class) != null) {
                //PostPara类型的注解
                Object o = json.get(parameter.getName());
                if (o != null) {
                    if (parameter.getType().isAssignableFrom(o.getClass())) {
                        invocation.setArg(index, o);
                    } else {
                        //参数类型转化
                        if (!BaseDataConvertUtil.inConvertType(o)) {
                            o = o.toString();
                        }
                        o = BaseDataConvertUtil.convert(o, parameter.getType());
                        if (o != null) {
                            if (parameter.getType().isAssignableFrom(o.getClass())) {
                                invocation.setArg(index, o);
                            } else {
                                throw new CustomException(parameter.getName(),
                                        parameter.getType().getSimpleName());
                            }
                        }
                    }
                }
            } else {
//                invocation.setArg(index, null);
            }
        }
    }
}
